#include "serpentd.h"

int main(int argc, char** argv, char** envp) {
	int opt,err,ret;
	serpentd_conf config;
	serpent_data config_file;
	FILE * mgr;
	serpent_data mgr_file;
	serpent_mgr q_mgr;
	
	serpent_data x;
	serpent_bool do_init = FALSE;
	
	strcpy(config_file,"\0");
	while( ( opt = getopt(argc,argv,"vfc:i") ) != -1) {
		switch(opt) {
			case 'v':
				version();
				return(0);
				break;
			case 'f':
				break;
			case 'c':
				strncpy(config_file, optarg, sizeof(config_file));
				break;
			case 'h':
				usage();				
				break;
			case 'i':
				do_init = TRUE;
				break;
			default:
				usage();
		}
	}
	
	if( strlen(config_file) <= 0 )
	{
		strncpy(config_file, SERPENTD_CONFIG, sizeof(config_file));
	}

	config = get_config(config_file);

	if( do_init == TRUE )
	{
		init_mgr(config);
		return(0);
	}
	
	
#ifndef DEBUG
	if( is_root() == FALSE ) 
	{
		printf("ERROR: This program needs to run as the superuser.\n");
		return(1);
	}
#endif
	
	strncpy(mgr_file, config.serpent_run, sizeof(mgr_file));
	if( ( strlen(mgr_file) + strlen("/mgr") ) < sizeof(serpent_data) )
		strncat(mgr_file, "/mgr", strlen("/mgr"));
	
	if( ( mgr = fopen(mgr_file,"r+") ) == NULL )
	{
		err = errno;
		printf("Initialization error(%s): %s\n", mgr_file, strerror(err));
		exit(1);
	}
	
	fread(&q_mgr, sizeof(serpent_mgr), 1, mgr);
	
	// OK, map everything from here to memory for realtime; mlockall() 
	// start main loop -> start queues -> functionality
	
	ret = serpent_mainloop();
	
	if( fclose(mgr) != 0 ) 
	{
		err = errno;
		printf("ERROR: %s\n",strerror(err));
	}
	
	return(ret);
}

void usage(void) {
	version();
	printf("serpentd: -fi -c <config>\n"
		   "\t-f run in foreground\n"
		   "\t-i initialize serpent manager database\n"
		   "\t-c <config>\n"
		   );
	exit(-1);
}

void version(void) {
	printf("serpent version: %s by %s under %s, %s\n", VERSION, AUTHOR, LICENSE, BUILD);
}

serpentd_conf get_config(serpent_data config_file) {
	serpentd_conf c;
	FILE * fp;
	int err;
	size_t n;
	char * line;
	serpent_data var;
	serpent_data cont;
	
	if( strcmp(SERPENTD_CONFIG, config_file) != 0 ) 
	{
		strncpy(c.serpent_run, config_file,sizeof(c.serpent_run));
	}
	else if(strlen(config_file) == 0)
	{
		strncpy(c.serpent_run, SERPENTD_CONFIG,sizeof(c.serpent_run));
	}
	
	if( ( fp = fopen(config_file,"r") ) == NULL )
	{
		err = errno;
		printf("ERROR(%s): %s\nNo config file available, exiting!\n",config_file,strerror(err));
		exit(1);
	}
	
	while( getline(&line, &n, fp) != -1 ) {
		if( strncmp(line," ", 1) != 0 && 
		   	strncmp(line,"#",1) && 
		   	strncmp(line,"\n",1) ) 
		{
			if( strncmp(line,"SERPENTDRUN", strlen("SERPENTDRUN")) == 0 )
			{
				get_variable (line, &var, &cont);
				strcpy(c.serpent_run,cont);
			}
			
			if( strncmp(line,"SERPENTDPID", strlen("SERPENTDPID")) == 0 )
			{
				get_variable (line, &var, &cont);
				strcpy(c.serpent_pid,cont);
			}
			
			if( strncmp(line,"SERPENTDUID", strlen("SERPENTDUID")) == 0 )
			{
				get_variable (line, &var, &cont);
				strcpy(c.serpent_uid,cont);
			}
			
			if( strncmp(line,"SERPENTDGID", strlen("SERPENTDGID")) == 0 )
			{
				get_variable (line, &var, &cont);
				strcpy(c.serpent_gid,cont);
			}

		}
	}
	
	if( fclose(fp) != 0 ) 
	{
		err = errno;
		printf("ERROR: %s\n",strerror(err));
	}
	
	return(c);
}

void get_variable(serpent_data line, serpent_data* variable, serpent_data* content) {
	int i,s,d,z;
	serpent_bool found1;
	
	s=0;
	found1 = FALSE;
	
	for( i = 0; i < strlen(line); i++ )
	{
		if( line[i] == '=' && line[i+1] == '"' ) 
		{
			s = i;
			d = i+2;
			found1 = TRUE;
		}
		
		if( found1 == TRUE && line[i] == '"' )
			z = i;
	}
	
	if( s == 0 )
		return;
	
	memset(variable, '\0', sizeof(variable));
	memset(content, '\0', sizeof(content));
	strncpy((char*)variable, line, s);
	strncpy((char*)content, (char*)&line[d], strlen(line) - (strlen((char*)variable)+4) );
}

serpent_bool init_mgr(serpentd_conf conf) {
	FILE * f;
	int err;
	serpent_mgr mgr;
	size_t retf;
	serpent_data file;
	
	strncpy(file,conf.serpent_run,sizeof(file));
	strncat(file,"/mgr",sizeof("/mgr"));
	
	if( ( f = fopen(file, "w+") ) == NULL ) 
	{
		err = errno;
		printf("ERROR(%s): %s\n",file,strerror(err));
		return(FALSE);
	}
	
	retf = fwrite(&mgr, sizeof(mgr), 1, f);
	fprintf(stderr, "datasize: %d\n", retf);
	
	if( fclose(f) != 0 )
	{
		err = errno;
		printf("ERROR(%s): %s\n",file,strerror(err));
		return(FALSE);
	}
	
}

serpent_bool is_root(void) {
	int err;
	uid_t uid;
	
	if( ( uid = getuid() ) != 0 )
		return(FALSE);
	
	if( seteuid(0) != 0 )
	{
		err = errno;
		printf("ERROR: %s\n",strerror(err));
		return(FALSE);
	}
	
	seteuid(uid);
	return(TRUE);
	
}

int serpent_mainloop(void)
{
	return(0);
}
